﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.model.Instance;
using l1cs.server.serverpackets;

namespace l1cs.server.model
{
    public class L1ChatParty
    {
        private static Logger _log = Logger.getLogger( typeof( L1ChatParty ).FullName );

        private List<L1PcInstance> _membersList = new List<L1PcInstance>();

        private L1PcInstance _leader = null;

        public void addMember( L1PcInstance pc )
        {
            if ( pc == null )
            {
                throw new NullReferenceException();
            }
            if ( _membersList.Count == Config.MAX_CHAT_PT && !_leader.isGm()
                    || _membersList.Contains( pc ) )
            {
                return;
            }

            if ( _membersList.Count == 0 )
            {
                // 最初のPTメンバーであればリーダーにする
                setLeader( pc );
            }

            _membersList.Add( pc );
            pc.setChatParty( this );
        }

        private void removeMember( L1PcInstance pc )
        {
            if ( !_membersList.Contains( pc ) )
            {
                return;
            }

            _membersList.Remove( pc );
            pc.setChatParty( null );
        }

        public bool isVacancy()
        {
            return _membersList.Count < Config.MAX_CHAT_PT;
        }

        public int getVacancy()
        {
            return Config.MAX_CHAT_PT - _membersList.Count;
        }

        public bool isMember( L1PcInstance pc )
        {
            return _membersList.Contains( pc );
        }

        private void setLeader( L1PcInstance pc )
        {
            _leader = pc;
        }

        public L1PcInstance getLeader()
        {
            return _leader;
        }

        public bool isLeader( L1PcInstance pc )
        {
            return pc.getId() == _leader.getId();
        }

        public String getMembersNameList()
        {
            String _result = "";
            foreach ( L1PcInstance pc in _membersList )
            {
                _result = _result + pc.getName() + " ";
            }
            return _result;
        }

        private void breakup()
        {
            L1PcInstance[] members = getMembers();

            foreach ( L1PcInstance member in members )
            {
                removeMember( member );
                member.sendPackets( new S_ServerMessage( 418 ) ); // パーティーを解散しました。
            }
        }

        public void leaveMember( L1PcInstance pc )
        {
            L1PcInstance[] members = getMembers();
            if ( isLeader( pc ) )
            {
                // パーティーリーダーの場合
                breakup();
            }
            else
            {
                // パーティーリーダーでない場合
                if ( getNumOfMembers() == 2 )
                {
                    // パーティーメンバーが自分とリーダーのみ
                    removeMember( pc );
                    L1PcInstance leader = getLeader();
                    removeMember( leader );

                    sendLeftMessage( pc, pc );
                    sendLeftMessage( leader, pc );
                }
                else
                {
                    // 残りのパーティーメンバーが２人以上いる
                    removeMember( pc );
                    foreach ( L1PcInstance member in members )
                    {
                        sendLeftMessage( member, pc );
                    }
                    sendLeftMessage( pc, pc );
                }
            }
        }

        public void kickMember( L1PcInstance pc )
        {
            if ( getNumOfMembers() == 2 )
            {
                // パーティーメンバーが自分とリーダーのみ
                removeMember( pc );
                L1PcInstance leader = getLeader();
                removeMember( leader );
            }
            else
            {
                // 残りのパーティーメンバーが２人以上いる
                removeMember( pc );
            }
            pc.sendPackets( new S_ServerMessage( 419 ) ); // パーティーから追放されました。
        }

        public L1PcInstance[] getMembers()
        {
            return _membersList.ToArray();
        }

        public int getNumOfMembers()
        {
            return _membersList.Count;
        }

        private void sendLeftMessage( L1PcInstance sendTo, L1PcInstance left )
        {
            // %0がパーティーから去りました。
            sendTo.sendPackets( new S_ServerMessage( 420, left.getName() ) );
        }
    }

}
